﻿using Microsoft.JScript;
using Microsoft.JScript.Vsa;
using Noesis.Javascript;
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JSRun
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            object[] testParams = new object[1];
            testParams[0] = "wwwww";
          //this.txtRes.Text = JS_JScriptCodeProvider.JScriptRun("test",testParams).ToString();



            //1
            this.txtRes.Text = JS_MicrosoftJScriptVsa.Run(this.rTxtJS.Text);
            //2
            this.txtRes.Text = JS_MSScriptControl.ExecuteScript_MSScriptControl(this.rTxtJS.Text, "");

            //3
            this.txtRes.Text = JS_Noesis.Run(this.rTxtJS.Text);// 需要定义res变量
        }
    }





    //1Microsoft.JScript
    //动态编译调用类方法
    public class JS_JScriptCodeProvider
    {
        private static readonly CodeDomProvider _provider = new Microsoft.JScript.JScriptCodeProvider();
        private static Type _evaluateType;
        private const string scriptStr = @"package fhs  
             {  
                     public class MyJs  
                     {  
 　　                    public static function test(paramr1)  
 　　                    {   
                             var retString  =   paramr1+ '是无敌的!';  
                             return retString;  
 　　                    }  
 　　  
                     }  
             }";
        public static object JScriptRun(string jsMethodName, object[] testParams=null)
        {
            //编译的参数  
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;
            CompilerResults results = _provider.CompileAssemblyFromSource(parameters, scriptStr);
            Assembly assembly = results.CompiledAssembly;

            //动态编译脚本中的内容  
            _evaluateType = assembly.GetType("fhs.MyJs");

            //执行指定的方法并传参数  
            object retObj = _evaluateType.InvokeMember(jsMethodName, BindingFlags.InvokeMethod,
                        null, null, testParams);
            return retObj;
        }
    }  

    /*
        该类需要你添加对程序集 Microsoft.JScript 的引用；如果把“current version with JScriptCodeProvider” 部分代码替换为“deprecated version with Vsa”部分代码，你还需要添加对程序集 Microsoft.Vsa 的引用。

　　代码段末尾注释掉的部分是用 Microsoft.JScript.Vsa.VsaEngine 作为脚本引擎来完成 Evaluate 工作；但 VsaEngine （包括其所实现的 IVsaEngine 接口）在 .NET Framework 2.0 中已经被 deprecated ，所以如果你在新版本下编译的话，会得到如下的警告信息：“Microsoft.JScript.Vsa.VsaEngine”已过时:“Use of this type is not recommended because it is being deprecated in Visual Studio 2005; there will be no replacement for this feature. Please see the ICodeCompiler documentation for additional help.”

　　这样的 Evaluate 方法一个显而易见的用途就是解析 JSON 数据。 JSON 的数据格式实际上是 JavaScript 对象定义语法的子集，所以使用这个 Framework 所提供的脚本引擎来解析得到的 JSON 格式的数据就比自己写一个 Parser 来的轻松得多。比如：
string jsStr = "( {'timeString':'Time is: ' + new Date(),'dateValue':new Date()} )";
Microsoft.JScript.JSObject obj = (Microsoft.JScript.JSObject) JSEvaluator.EvalToObject(jsStr);
MessageBox.Show(obj["timeString"].ToString());
MessageBox.Show(obj["dateValue"].ToString());
Microsoft.JScript.DateObject tmpV = (Microsoft.JScript.DateObject)obj["dateValue"];
DateTime dt =  (DateTime) Microsoft.JScript.Convert.Coerce(tmpV, typeof(DateTime));
MessageBox.Show(dt.ToString());
    只需要得到一个 JSObject ，就可以通过对象的 key 名访问到每一个变量。
     */
    public class JSEvaluator
    {
        public static int EvalToInteger(string statement)
        {
            string s = EvalToString(statement);
            return int.Parse(s.ToString());
        }

        public static double EvalToDouble(string statement)
        {
            string s = EvalToString(statement);
            return double.Parse(s);
        }

        public static string EvalToString(string statement)
        {
            object o = EvalToObject(statement);
            return o.ToString();
        }


        // current version with JScriptCodeProvider BEGIN  
        ///*  

        public static object EvalToObject(string statement)
        {
            return _evaluatorType.InvokeMember(
                  "Eval",
                  BindingFlags.InvokeMethod,
                  null,
                  _evaluator,
                  new object[] { statement }
                 );
        }


        static JSEvaluator()
        {
            JScriptCodeProvider compiler = new JScriptCodeProvider();

            CompilerParameters parameters;
            parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;

            CompilerResults results;
            results = compiler.CompileAssemblyFromSource(
                                            parameters, _jscriptSource);

            Assembly assembly = results.CompiledAssembly;
            _evaluatorType = assembly.GetType("JSEvaluator.JSEvaluator");

            _evaluator = Activator.CreateInstance(_evaluatorType);
        }

        private static object _evaluator = null;
        private static Type _evaluatorType = null;
        private static readonly string _jscriptSource =
          @"package JSEvaluator 
         { 
            class JSEvaluator 
            { 
             public function Eval(expr : String) : Object 
             { 
              return eval(expr); 
             } 
            } 
         }";

        //*/  
        // current version with JScriptCodeProvider END  


        // deprecated version with Vsa BEGIN  
        /* 

        public static Microsoft.JScript.Vsa.VsaEngine Engine = 
                      Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); 

        public static object EvalToObject(string JScript) 
        { 
          object Result = null; 
          try 
          { 
            Result = Microsoft.JScript.Eval.JScriptEvaluate( 
                                                    JScript, Engine); 
          } 
          catch (Exception ex) 
          { 
            return ex.Message; 
          } 
          return Result; 
        } 

         */
        // deprecated version with Vsa END  
    }
    public class JS_MicrosoftJScriptVsa
    {
        public  static string Run(string JScript)
        {
            string Result = null;
            try
            {
                VsaEngine Engine = VsaEngine.CreateEngine();
                Result = Microsoft.JScript.Eval.JScriptEvaluate(JScript, Engine).ToString();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return Result;
        }
    }



    //2MSScriptControl
    public class JS_MSScriptControl
    {
        //string jsStr = File.ReadAllText(jsPath, jsEncoding);
        //string jsFun = string.Format(@"decrypt_cbc_('{0}')", strEn);
        //string jsResult = ExecuteScript_MSScriptControl(jsFun, jsStr);
        public static string Run(string JScript)
        {
            string Result = null;
            try
            {
                VsaEngine Engine = VsaEngine.CreateEngine();
                Result = Microsoft.JScript.Eval.JScriptEvaluate(JScript, Engine).ToString();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return Result;
        }
        /// <summary>
        /// 执行JS
        /// </summary>
        /// <param name="sExpression">参数体</param>
        /// <param name="sCode">JavaScript代码的字符串</param>
        /// <returns></returns>
        public static string ExecuteScript_MSScriptControl(string sExpression, string sCode)
        {
            MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();
            scriptControl.UseSafeSubset = true;
            scriptControl.Language = "JScript";
            scriptControl.AddCode(sCode);
            try
            {
                string str = scriptControl.Eval(sExpression).ToString();
                return str;
            }
            catch (Exception ex)
            {
                string str = ex.Message;
            }
            return null;
        }
    }
    public class CJSHelper
    {
        string _jsCodes = "";
        Encoding jsEncoding;
        public CJSHelper(string JsCode)
        {
            _jsCodes = JsCode;
        }
        public CJSHelper(string Path, Encoding en = null)
        {
            jsEncoding = en;
            if (jsEncoding == null)
                jsEncoding = Encoding.Default;
            _jsCodes = File.ReadAllText(Path, jsEncoding);
        }



        public string ExecuteScript_MSScriptControl(string sExpression)
        {
            MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();
            scriptControl.UseSafeSubset = true;
            scriptControl.Language = "JScript";
            scriptControl.AddCode(_jsCodes);
            try
            {
                string str = scriptControl.Eval(sExpression).ToString();
                return str;
            }
            catch (Exception ex)
            {
                string str = ex.Message;
            }
            return null;
        }
        public string ExecuteScript_MSScriptControl(string sExpression, string JsCode)
        {
            MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();
            scriptControl.UseSafeSubset = true;
            scriptControl.Language = "JScript";
            scriptControl.AddCode(JsCode);
            try
            {
                string str = scriptControl.Eval(sExpression).ToString();
                return str;
            }
            catch (Exception ex)
            {
                string str = ex.Message;
            }
            return null;
        }
    }


    //3Noesis.Javascript
    public class SystemConsole
    {
        public SystemConsole() { }

        public void Print(string iString)
        {
            Console.WriteLine(iString);
        }
    }
    /// <summary>
    /// 需要定义res变量
    /// </summary>
    public class JS_Noesis
    {
        public static string RunTest()
        {
            using (JavascriptContext context = new JavascriptContext())
            {
                // Setting the externals parameters of the context
                //context.SetParameter("console", new SystemConsole());
                //context.SetParameter("message", "Hello World !");
                context.SetParameter("number", 1);

                // Running the script
                //context.Run("var i; for (i = 0; i < 5; i++) console.Print(message + ' (' + i + ')'); number += i;");
                context.Run("var i; for (i = 0; i < 5; i++) number += i;");

                // Getting a parameter
                //Console.WriteLine("" + context.GetParameter("number").ToString());
                return context.GetParameter("number").ToString();
            }
        }
        public static string Run(string jsCode)
        {
            string Result = null;
            try
            {
                using (JavascriptContext context = new JavascriptContext())
                {
                    context.Run(jsCode);
                    Result = context.GetParameter("res").ToString();
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return Result;
        }
    }





    //Microsoft.Vsa
    /*
    public class ScriptControl
    {
        static ScriptControl()
        {

        }
        public void Close()
        {
            engine.Close();

        }
        private IVsaEngine engine;
        private String rootNamespace;
        private String rootMoniker;
        private ScriptControlSite site;
        public IVsaError Error
        {
            get { return site.Error; }
        }
        public void Run()
        {
            if (!engine.IsRunning)
            {
                if (!engine.IsCompiled)
                    engine.Compile();
                if (engine.IsCompiled == false)
                {
                    String message = "Error on line " + Error.Line + ", col " + Error.EndColumn + "/r/n" + Error.LineText + "/r" + Error.Description;
                    throw new Exception(message);

                }

                engine.Run();
            }
        }

        public void AddCode(String itemName, String code)
        {
            IVsaCodeItem item = GetCodeItem(itemName);
            item.AppendSourceText(code);
        }
        public ScriptControl(String rootNamespace)
            : this(rootNamespace, "SharpnessdotnetApp://SharpnessdotnetProject", "Microsoft.VisualBasic.Vsa.VsaEngine")
        {
        }

        public ScriptControl(String rootNamespace, String rootMoniker, String language)
        {

            this.rootNamespace = rootNamespace;
            this.rootMoniker = rootMoniker;
            switch (language.ToLower())
            {
                case "microsoft.visualbaisc.vsa":
                    engine = new VsaEngine();
                    break;
                case "microsoft.jscript.vsa":
                    engine = new Microsoft.JScript.Vsa.VsaEngine();
                    break;
                default:
                    engine = new VsaEngine();
                    break;

            }
            site = new ScriptControlSite();
            engine.RootMoniker = rootMoniker;
            engine.Site = site;
            engine.InitNew();
            engine.RootNamespace = rootNamespace;

        }
        public void AddReference(String fullName)
        {
            AddReference(Assembly.Load(fullName));
        }
        public void AddReference(Type t)
        {
            AddReference(t.Assembly);
        }
        public void AddReference(Assembly asm)
        {

            try
            {
                IVsaReferenceItem item = (IVsaReferenceItem)engine.Items.CreateItem(asm.Location, VsaItemType.Reference, VsaItemFlag.None);

                item.AssemblyName = asm.Location;
            }
            catch (Microsoft.Vsa.VsaException exception)
            {
                string message = exception.Message;
            }


        }
        public void AddObject(String name, Object obj)
        {
            site.AddObject(name, obj);
            Type t = obj.GetType();
            if (!(engine is VsaLoader))
            {
                IVsaGlobalItem GlobalItem;
                GlobalItem = (IVsaGlobalItem)engine.Items.CreateItem(name, VsaItemType.AppGlobal, VsaItemFlag.None);

                GlobalItem.TypeString = t.FullName;
            }
        }
        public void AddEventSourceObject(String itemName, String name, Object obj)
        {
            if (!(engine is VsaLoader))
            {
                IVsaCodeItem codeItem;
                codeItem = GetCodeItem(itemName);

                if (codeItem.SourceText == null || codeItem.SourceText.Length == 0)
                    throw new InvalidOperationException("no scripts to run");
                codeItem.AddEventSource(name, obj.GetType().FullName);

            }
            site.AddEventSourceObject(itemName, name, obj);
        }
        public object Invoke(string methodName, object[] arguments)
        {
            if ((null == methodName) || (0 == String.Compare(methodName, "")))
                throw new ArgumentNullException("methodName");
            if (false == engine.IsRunning)
                Run();
            char[] seprators = { '.' };
            string[] parts;
            parts = methodName.Split(seprators);
            if (parts.Length < 2)
                throw new ArgumentNullException("methodName");
            int procNamePos = methodName.LastIndexOf('.');
            string typeName = methodName.Substring(0, procNamePos);
            string procName = methodName.Substring(procNamePos + 1);
            if (null == procName)
                throw new ArgumentNullException("methodName");
            string RootNamespace;
            string Fullname;
            RootNamespace = engine.RootNamespace;
            Fullname = RootNamespace + "." + typeName;
            Type clsType = engine.Assembly.GetType(Fullname, true, true);
            MethodInfo method = clsType.GetMethod(procName);
            if (null == method)
                throw new ArgumentNullException("methodName");
            return method.Invoke(null, arguments);
        }
        private IVsaCodeItem GetCodeItem(String itemName)
        {
            if (itemName == null || itemName.Length == 0)
                itemName = "Module1";
            IVsaCodeItem codeItem = null;
            try
            {
                codeItem = (IVsaCodeItem)engine.Items[itemName];
            }
            catch
            {
            }
            if (codeItem == null)
                codeItem = (IVsaCodeItem)engine.Items.CreateItem(itemName, VsaItemType.Code, VsaItemFlag.None);
            return codeItem;
        }
        private class ScriptControlSite : IVsaSite
        {
            private IDictionary hostObjects;
            private IDictionary eventSourceObjects;
            private byte[] pe = null;
            private byte[] pdb = null;
            public IVsaError Error;

            private byte[] Read(String filename)
            {
                FileStream fs = new FileStream(filename, FileMode.Open);
                BinaryReader br = new BinaryReader(fs);
                return br.ReadBytes((int)fs.Length);
            }

            public void LoadFrom(String pefile, String pdbfile)
            {
                pe = Read(pefile);
                pdb = Read(pdbfile);
            }

            public ScriptControlSite()
            {
                this.hostObjects = new Hashtable();
                this.eventSourceObjects = new Hashtable();
            }

            public void AddObject(String name, Object obj)
            {
                this.hostObjects.Add(name, obj);

            }

            public void AddEventSourceObject(String itemName, String name, Object obj)
            {
                IDictionary eventSource;
                if (!eventSourceObjects.Contains(itemName))
                {
                    eventSourceObjects.Add(itemName, new Hashtable());

                }
                eventSource = (IDictionary)eventSourceObjects[itemName];
                eventSource.Add(name, obj);
            }

            #region IVsaSite Members

            public object GetEventSourceInstance(string itemName, string eventSourceName)
            {
                IDictionary eventSoruce = (IDictionary)eventSourceObjects[itemName];
                return eventSoruce[eventSourceName];
            }

            public object GetGlobalInstance(string name)
            {
                return hostObjects[name];
            }

            public void Notify(string notify, object info)
            {
            }

            public bool OnCompilerError(IVsaError error)
            {
                Error = error;

                return false;
            }

            public void GetCompiledState(out byte[] pe, out byte[] debugInfo)
            {
                pe = this.pe;
                debugInfo = this.pdb;
            }

            #endregion
        }
    }
    */


    #region DES3脚本加密

    public class DES3_JS
    {
        void DES3Test()
        {
            /*
            //string ddd = "{\"BSFIT_DEVICEID\":\"2c5e8e6759b2494683f73facebc8abc1\",\"last_login_from_\":\"4\","merchant_code_":"","mobile_phone_":"13585538004","password_":"aI+n29ALYSdDjTO08uVRUg==","verify_code_":""}";
            //Encoding.UTF8.GetString(Convert.FromBase64String(s));//base64解码
            //Convert.ToBase64String(Encoding.UTF8.GetBytes(s));//base64编码
            string strTest =   "{\"BSFIT_DEVICEID\":\"5d155fbebff84ed4b168a5168e9dabc0\",\"last_login_from_\":\"4\",\"merchant_code_\":\"\",\"mobile_phone_\":\"13578944646\",\"password_\":\"DAvQDifON8KV/pRmDk/AYg==\",\"verify_code_\":\"\"}";
            string strEn = " CQzbQBy4xllllKLbUxyHe0uFQfvBsSu44VYaMIykdXIi82X3R9mK0CaS0Xt4qSidQmDbRVKd6SmwnFpXQ+1cebcCt8Hccqc5PFHwodnqKnypgfUmm2NpY9JArwluC6P8HQQrhw4/vvGRq4s0vc/lH+j+YHk9yu2ETYmYfofSzq1+sCBqVyrDyWBFtI3ah4FDV2QtPf7nc1EaVDQhWpwe8AuwsH5AVO9jmpfdUIPU9Xxqd7bo0Tsxkw==";
            string jsFun = "";
            string jsResult = "";

            string jsPath = AppDomain.CurrentDomain.BaseDirectory + "yrd\\Des3.js";
            Encoding jsEncoding = Encoding.GetEncoding("GB2312");
            //Encoding jsEncoding = Encoding.UTF8;
            string jsStr = File.ReadAllText(jsPath, jsEncoding);

            //解密
            //strEn = Encoding.UTF8.GetString(Convert.FromBase64String(strEn));//base64解码
            jsFun = string.Format(@"decrypt_cbc_('{0}')", strEn);
            jsResult = ExecuteScript_MSScriptControl(jsFun, jsStr);
            //jsResult = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(jsResult));
            MessageBox.Show(jsResult);

            //加密
            jsFun = string.Format(@"encrypt_cbc_('{0}')", strTest);
            jsResult = ExecuteScript_MSScriptControl(jsFun, jsStr);
            //jsResult = Convert.ToBase64String(Encoding.UTF8.GetBytes(jsResult));
            //MessageBox.Show(jsResult);

             //解密
            //jsResult = Encoding.UTF8.GetString(Convert.FromBase64String(jsResult));//base64解码
            jsFun = string.Format(@"decrypt_cbc_('{0}')", jsResult);
            jsResult = ExecuteScript_MSScriptControl(jsFun, jsStr);
            MessageBox.Show(jsResult);


            //解密加密
            jsFun = string.Format(@"decrypt_cbc_('{0}')", strEn);
            jsResult = ExecuteScript_MSScriptControl(jsFun, jsStr);
            MessageBox.Show(jsResult);
            jsFun = string.Format(@"encrypt_cbc_('{0}')", jsResult);
            jsResult = ExecuteScript_MSScriptControl(jsFun, jsStr);
            MessageBox.Show(jsResult);
            */

            Des3.Test();
            //var genKey = "secretKeyforfxdsecretKey";
            //var des3iv = "1qaz2wsxZ";
            //Des3.Des3DecodeCBC(genKey, des3iv, strEn);

            
    //        string pathHello = AppDomain.CurrentDomain.BaseDirectory + "yrd\\Hello.js";
    //        Encoding encoding = Encoding.GetEncoding("GB2312");
    //        string str2Hello = File.ReadAllText(pathHello, encoding);
    //        string funHello = string.Format(@"sayHello('{0}')", this.txt_Url.Text.Trim());
    //        string resultHello = ExecuteScript(funHello, str2Hello);
    //        MessageBox.Show(resultHello);

    //        string enStr="";
    //        string path = AppDomain.CurrentDomain.BaseDirectory + "yrd\\Des3.js";
    //        //Encoding encoding = Encoding.GetEncoding("GB2312");
    //        //Encoding encoding = Encoding.UTF8;
    //        string str2 = File.ReadAllText(path, encoding);
    //        str2 += str2Hello;
    //        /*
    //        var encryptKey="secretKeyforfxdsecretKeyforfxd";
    //        var des3iv = '1qaz2wsxZ';
    //        //3DES加密，CBC/PKCS5Padding
    //        encrypt: function(input) {
    //        var genKey = genkey(encryptKey, 0, 24);
    //        return btoa(des(genKey.key, input, 1, 1, des3iv, 1));

    //        ////3DES解密，CBC/PKCS5Padding
    //        decrypt: function(input) {
    //        var genKey = genkey(encryptKey);
    //        return des(genKey.key, atob(input), 0, 1, des3iv, 1);
    //        */
    //        string funHello2 = string.Format(@"sayHello2('{0}')", this.txt_Url.Text.Trim());
    //        resultHello = ExecuteScript(funHello2, str2);
    //        MessageBox.Show(resultHello);
    //        string funHello3 = string.Format(@"sayHello3('{0}')", this.txt_Url.Text.Trim());
    //        resultHello = ExecuteScript(funHello3, str2);
    //        MessageBox.Show(resultHello);

    //    //var genKey="secretKeyforfxdsecretKey";
    //    //var des3iv = "1qaz2wsxZ";

    ////return des(genKey.key, atob(input), 0, 1, des3iv, 1);
    //    string funHello5 = string.Format(@"des('{0}','{1}',0,1,'1qaz2wsxZ',1)", genKey, this.txt_Url.Text.Trim());
    //    resultHello = ExecuteScript(funHello5, str2);
    //MessageBox.Show(resultHello);


    //        string fun = string.Format(@"des3Decrypt('{0}')", this.txt_Url.Text.Trim());
    //        //string fun = string.Format(@"des(genKey.key, atob(input), 0, 1, des3iv, 1)", this.txt_Url.Text.Trim());
    //        //string fun = string.Format(@"DES3.decrypt('{0}')", this.txt_Url.Text.Trim());
    //        string result = ExecuteScript(fun, str2);
    //        MessageBox.Show(result);
    //        //this.web.Navigate(this.txt_Url.Text, "", null, "User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16\r\n");

        }

    /// <summary>
    /// DES3加密解密
    /// </summary>
    public class Des3
    {
        public static string Des3DecodeCBC(string strKey, string strIV, string StrData)
        {
            Encoding encoding = Encoding.UTF8;
            byte[] key = System.Convert.FromBase64String(strKey);
            byte[] iv = System.Convert.FromBase64String(strIV);
            //byte[] iv = new byte[] {'1','q','a','z','2','w','s','x','Z' };      //当模式为ECB时，IV无用
            byte[] data = encoding.GetBytes(StrData);
            //byte[] str3 = Des3.Des3EncodeCBC(key, iv, data);
            byte[] str4 = Des3.Des3DecodeCBC(key, iv, data);
            //System.Console.WriteLine(Convert.ToBase64String(str3));
            //System.Console.WriteLine(encoding.GetString(str4));
            return encoding.GetString(str4);
        }


        #region CBC模式**
        /// <summary>
        /// DES3 CBC模式加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="iv">IV</param>
        /// <param name="data">明文的byte数组</param>
        /// <returns>密文的byte数组</returns>
        public static byte[] Des3EncodeCBC(byte[] key, byte[] iv, byte[] data)
        {
            //复制于MSDN
            try
            {
                // Create a MemoryStream.
                MemoryStream mStream = new MemoryStream();
                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
                tdsp.Mode = CipherMode.CBC;             //默认值
                tdsp.Padding = PaddingMode.PKCS7;       //默认值
                // Create a CryptoStream using the MemoryStream 
                // and the passed key and initialization vector (IV).
                CryptoStream cStream = new CryptoStream(mStream,
                    tdsp.CreateEncryptor(key, iv),
                    CryptoStreamMode.Write);
                // Write the byte array to the crypto stream and flush it.
                cStream.Write(data, 0, data.Length);
                cStream.FlushFinalBlock();
                // Get an array of bytes from the 
                // MemoryStream that holds the 
                // encrypted data.
                byte[] ret = mStream.ToArray();
                // Close the streams.
                cStream.Close();
                mStream.Close();
                // Return the encrypted buffer.
                return ret;
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }
        /// <summary>
        /// DES3 CBC模式解密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="iv">IV</param>
        /// <param name="data">密文的byte数组</param>
        /// <returns>明文的byte数组</returns>
        public static byte[] Des3DecodeCBC(byte[] key, byte[] iv, byte[] data)
        {
            try
            {
                // Create a new MemoryStream using the passed 
                // array of encrypted data.
                MemoryStream msDecrypt = new MemoryStream(data);
                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
                tdsp.Mode = CipherMode.CBC;
                tdsp.Padding = PaddingMode.PKCS7;
                // Create a CryptoStream using the MemoryStream 
                // and the passed key and initialization vector (IV).
                CryptoStream csDecrypt = new CryptoStream(msDecrypt,
                    tdsp.CreateDecryptor(key, iv),
                    CryptoStreamMode.Read);
                // Create buffer to hold the decrypted data.
                byte[] fromEncrypt = new byte[data.Length];
                // Read the decrypted data out of the crypto stream
                // and place it into the temporary buffer.
                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
                //Convert the buffer into a string and return it.
                return fromEncrypt;
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }
        #endregion
        #region ECB模式
        /// <summary>
        /// DES3 ECB模式加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="iv">IV(当模式为ECB时，IV无用)</param>
        /// <param name="str">明文的byte数组</param>
        /// <returns>密文的byte数组</returns>
        public static byte[] Des3EncodeECB(byte[] key, byte[] iv, byte[] data)
        {
            try
            {
                // Create a MemoryStream.
                MemoryStream mStream = new MemoryStream();
                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
                tdsp.Mode = CipherMode.ECB;
                tdsp.Padding = PaddingMode.PKCS7;
                // Create a CryptoStream using the MemoryStream 
                // and the passed key and initialization vector (IV).
                CryptoStream cStream = new CryptoStream(mStream,
                    tdsp.CreateEncryptor(key, iv),
                    CryptoStreamMode.Write);
                // Write the byte array to the crypto stream and flush it.
                cStream.Write(data, 0, data.Length);
                cStream.FlushFinalBlock();
                // Get an array of bytes from the 
                // MemoryStream that holds the 
                // encrypted data.
                byte[] ret = mStream.ToArray();
                // Close the streams.
                cStream.Close();
                mStream.Close();
                // Return the encrypted buffer.
                return ret;
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }
        /// <summary>
        /// DES3 ECB模式解密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="iv">IV(当模式为ECB时，IV无用)</param>
        /// <param name="str">密文的byte数组</param>
        /// <returns>明文的byte数组</returns>
        public static byte[] Des3DecodeECB(byte[] key, byte[] iv, byte[] data)
        {
            try
            {
                // Create a new MemoryStream using the passed 
                // array of encrypted data.
                MemoryStream msDecrypt = new MemoryStream(data);
                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
                tdsp.Mode = CipherMode.ECB;
                tdsp.Padding = PaddingMode.PKCS7;
                // Create a CryptoStream using the MemoryStream 
                // and the passed key and initialization vector (IV).
                CryptoStream csDecrypt = new CryptoStream(msDecrypt,
                    tdsp.CreateDecryptor(key, iv),
                    CryptoStreamMode.Read);
                // Create buffer to hold the decrypted data.
                byte[] fromEncrypt = new byte[data.Length];
                // Read the decrypted data out of the crypto stream
                // and place it into the temporary buffer.
                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
                //Convert the buffer into a string and return it.
                return fromEncrypt;
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }
        #endregion
        /// <summary>
        /// 类测试
        /// </summary>
        public static void Test()
        {
            System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
            //key为abcdefghijklmnopqrstuvwx的Base64编码
            byte[] key = System.Convert.FromBase64String("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");
            byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };      //当模式为ECB时，IV无用
            byte[] data = utf8.GetBytes("中国ABCabc123");
            System.Console.WriteLine("ECB模式:");
            byte[] str1 = Des3.Des3EncodeECB(key, iv, data);
            byte[] str2 = Des3.Des3DecodeECB(key, iv, str1);
            System.Console.WriteLine(System.Convert.ToBase64String(str1));
            System.Console.WriteLine(System.Text.Encoding.UTF8.GetString(str2));
            System.Console.WriteLine();
            System.Console.WriteLine("CBC模式:");
            byte[] str3 = Des3.Des3EncodeCBC(key, iv, data);
            byte[] str4 = Des3.Des3DecodeCBC(key, iv, str3);
            //System.Console.WriteLine(Convert.ToBase64String(str3));
            //System.Console.WriteLine(utf8.GetString(str4));
            //System.Console.WriteLine();
            string sss = "";
            sss = System.Convert.ToBase64String(str3);
            sss = System.Convert.ToBase64String(str3);
            //sss = utf8.GetString(sss);
            //sss = Convert.FromBase64String(sss);
            sss += "";

        }
    }
    }
    #endregion
}
